package cn.schoolwow.flow.monitor.domain.handler;

import cn.schoolwow.quickflow.flow.BusinessFlow;
import cn.schoolwow.quickflow.flow.CompositeBusinessFlow;
import cn.schoolwow.quickflow.listener.FlowMappingHandler;
import cn.schoolwow.quickflow.listener.SingleFlowListener;
import cn.schoolwow.quickflow.listener.TryCatchFinallyHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@Service
public class FlowMonitorFlowMappingHandler implements FlowMappingHandler {
    private Logger logger = LoggerFactory.getLogger(FlowMonitorFlowMappingHandler.class);

    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public BusinessFlow getFlow(String flowName) {
        Map<String, BusinessFlow> beanMap = applicationContext.getBeansOfType(BusinessFlow.class);
        Map<String, BusinessFlow> flowNameMap = new HashMap<>();
        Set<String> repeatFlowNameSet = new HashSet<>();
        for (BusinessFlow businessFlow : beanMap.values()) {
            String name = businessFlow.name();
            if(flowNameMap.containsKey(name)){
                repeatFlowNameSet.add(name);
            }
            flowNameMap.put(name, businessFlow);
        }
        if(!repeatFlowNameSet.isEmpty()){
            logger.info("存在重名流程!"+repeatFlowNameSet);
            throw new IllegalArgumentException("存在重名流程!重名流程个数:"+repeatFlowNameSet.size());
        }
        if (flowNameMap.containsKey(flowName)) {
            return flowNameMap.get(flowName);
        }
        return null;
    }

    @Override
    public CompositeBusinessFlow getCompositeBusinessFlow(String flowName) {
        Map<String,CompositeBusinessFlow> beanMap = applicationContext.getBeansOfType(CompositeBusinessFlow.class);
        Map<String,CompositeBusinessFlow> flowNameMap = new HashMap<>();
        Set<String> repeatFlowNameSet = new HashSet<>();
        for(CompositeBusinessFlow compositeBusinessFlow:beanMap.values()){
            String name = compositeBusinessFlow.name();
            if(flowNameMap.containsKey(name)){
                repeatFlowNameSet.add(name);
            }
            flowNameMap.put(name, compositeBusinessFlow);
        }
        if(!repeatFlowNameSet.isEmpty()){
            logger.info("存在重名流程!"+repeatFlowNameSet);
            throw new IllegalArgumentException("存在重名流程!重名流程个数:"+repeatFlowNameSet.size());
        }
        if(flowNameMap.containsKey(flowName)){
            return flowNameMap.get(flowName);
        }
        return null;
    }

    @Override
    public TryCatchFinallyHandler getTryCatchFinallyHandler(String handlerName) {
        Map<String, TryCatchFinallyHandler> beanMap = applicationContext.getBeansOfType(TryCatchFinallyHandler.class);
        for (TryCatchFinallyHandler tryCatchFinallyHandler : beanMap.values()) {
            if (tryCatchFinallyHandler.name().equalsIgnoreCase(handlerName)) {
                return tryCatchFinallyHandler;
            }
        }
        throw new IllegalArgumentException("tryCatchFinally处理器名称对应处理器不存在!名称:" + handlerName);
    }

    @Override
    public SingleFlowListener getSingleFlowListener(String handlerName) {
        Map<String, SingleFlowListener> beanMap = applicationContext.getBeansOfType(SingleFlowListener.class);
        for (SingleFlowListener singleFlowListener : beanMap.values()) {
            if (singleFlowListener.name().equalsIgnoreCase(handlerName)) {
                return singleFlowListener;
            }
        }
        throw new IllegalArgumentException("singleFlow处理器名称对应处理器不存在!名称:" + handlerName);
    }
}
